import re

from tg.decorators import expose

from webinfo import webinfo
from weberror.exceptions.errormiddleware import ErrorMiddleware

from controller_lookup import *
from middleware import *

def authkit_app(app):
    from authkit.authenticate import middleware
    def valid(environ, username, password):
        print 'Calling valid with %s:%s' % (username, password)
        return True
    config = {
        'authkit.setup.method':'basic',
        'authkit.basic.realm':'Test Realm',
        'authkit.basic.authenticate.function':valid,
        'authkit.setup.enable':'True',
        }
    app = middleware(app, app_conf = config)
    return app

def clutch_stack(root):
    app = ControllerDispatch()
    app = Validation(app)
    app = Identity(app)
    app = SATransaction(app)
    app = ControllerLookup(app, root)
    app = ClutchWrapper(app)
    app = authkit_app(app)
    app = ErrorMiddleware(app, debug=True)
    return app

class RegexController(object):

    def __init__(self, *urls):
        self._urls = []
        self._children = {}
        self.configure_urls(*urls)

    def configure_urls(self, *urls):
        for url, controller in urls:
            self._mount_controller(controller, *url.split('/'))

    def _merge_controller(self, other):
        self._urls = other._urls + self._urls
        d = dict(other._children)
        d.update(self._children)
        self._children = d

    def _mount_controller(self, controller, next, *remainder):
        if ':' in next:
            pattern, capture = next.rsplit(':', 1)
            if not pattern: pattern = '.*'
            pattern = '(?P<%s>%s)$' % (capture, pattern)
        else:
            pattern = next + '$'
        next_controller = self._children.get(pattern)
        if remainder:
            if next_controller is None:
                self._children[pattern] = next_controller = RegexController()
            next_controller._mount_controller(controller, *remainder)
        else:
            if next_controller is not None:
                controller.merge_controller(next_controller)
            self._children[pattern] = controller
            next_controller = controller
        self._urls.append((re.compile(pattern), next_controller))

    @expose()
    def lookup(self, next, *remainder):
        for pattern, controller in self._urls:
            m = pattern.match(next)
            if m:
                webinfo.request.environ['clutch.params'].update(m.groupdict())
                return controller, remainder
        return None

